home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Graphics Samples / viewPort Mania ƒ / graphics shell.c next >
Encoding:
C/C++ Source or Header  |  1996-04-21  |  13.6 KB  |  421 lines  |  [TEXT/MPS ]

  1. /**\
  2. |**| =====================================================================
  3. |**|
  4. |**|    graphics shell.c
  5. |**|
  6. |**|    This file is a shell that can be used to build "new" Graphics 
  7. |**|    applications.  It contains all of the required calls to use the "new"
  8. |**|    Graphics routines and QuickDraw (i.e. windows) together. You "quit" the
  9. |**|    application by clicking in the close box.  This shell does not use a menu.
  10. |**|
  11. |**|    The application is expected to supply the following functions which
  12. |**|    are called by this shell:
  13. |**|        void DoInitialization (WindowPtr);
  14. |**|        void DoDraw (WindowPtr);
  15. |**|        void DoDispose (WindowPtr);
  16. |**|        void DoClick (gxPoint, WindowPtr);
  17. |**|        void DoIdle (WindowPtr);
  18. |**|
  19. |**|
  20. |**|    Change History:
  21. |**|        3/90    New
  22. |**|        6/91    PLA  Updated the shell to reflect the changes in
  23. |**|                     "Graphics" v1.0d21.2.
  24. |**|        6/92    PLA  Made the following variables global: gDebugging,
  25. |**|                     gGiveMeValidation,gGraphicsHeapSize.
  26. |**|                     See the comments for detail in this file.
  27. |**|        9/93    PLA  Updated files to work with the ß2 "GXified"
  28. |**|                     interface files.
  29. |**|                     Worked around a problem with GXConvertQDPoint(..)
  30. |**|                     see the comments within the GetWindowBoundsShape(..)
  31. |**|                     call for details (below).
  32. |**|        12/93    PLA  Updated the comment above the GXNewGraphicsCLient call
  33. |**|                     to reflect the new fucntionality of this call in ß3. 
  34. |**|                     Removed the work around with GXConvertQDPoint (..)
  35. |**|                     where the call would not survive validation under ß2.
  36. |**|                     Under ß3 the call suceeds when validation is set.   PLA
  37. |**|        3/94    PLA  Removed the following varaibles: gDebugging &
  38. |**|                     gGiveMeValidation see the comments for details (below). 
  39. |**|                     Added a Gestalt check to see if GX has been installed.
  40. |**|                     Added extensive error checking to make sure the GX graphics
  41. |**|                     client has been created and the GX heap correctly allocated.
  42. |**|                     This shell will shut down at start-up and alert the user
  43. |**|                     to the problem and bail if: GX is not installed, we cannot
  44. |**|                     create the graphics client, or create a GX heap.
  45. |**|        4/94    PLA  Added the gxPoint as a parameter to the DoClick (..)
  46. |**|                     function to support hit testing. 
  47. |**|                     Added a check to see if the PowerPC QuickDrawGXLib is
  48. |**|                     installed. Search on "powerc" to find all of the changes
  49. |**|                     added to support Native QuickDraw GX on a Power Mac.  PLA
  50. |**|        8/94    DH   More changes made for universal header and clarity
  51. |**|                     Removed GetWindowBoundsShape(..) since it wasn't being
  52. |**|                     used after the workaround was removed 19/93
  53. |**|        4/96    cnn   Changed #if condition which surrounds the definition
  54. |**|                            of "qd" to work with MPW 3.4. Added (Ptr) coercion to
  55. |**|                            kUnresolvedSymbolAddress to allow comparison to
  56. |**|                            GXNewGraphicsClient. 
  57. |**|
  58. |**|    ©1990-1996  Apple Computer, Inc.
  59. |**|    All rights reserved.
  60. |**|
  61. |**| =====================================================================
  62. \**/
  63.  
  64.  
  65.  
  66. #include "graphics shell.h"
  67.  
  68.  
  69. /**\
  70. |**| ---------------------------------------------------------------------
  71. |**| ENUMS
  72. |**| ---------------------------------------------------------------------
  73. \**/
  74. enum { rWindResource = 128 };
  75.  
  76.  
  77. /**\
  78. |**| ---------------------------------------------------------------------
  79. |**| GLOBALS
  80. |**| ---------------------------------------------------------------------
  81. \**/
  82. Boolean            gQuitting = false;
  83. long            gSleep = 0;
  84. WindowPtr         gWindow;
  85. gxViewPort        gTheWindowsViewPort;    
  86.  
  87. #if GENERATINGCFM
  88.     QDGlobals        qd;
  89. #else
  90.     #ifndef SYMANTEC_C
  91.         #ifndef SYMANTEC_CPLUS
  92.         #define __MPW_ONLY__
  93.         #endif
  94.     #endif
  95.     
  96.     #if defined (__SC__) && defined (__MPW_ONLY__)
  97.     QDGlobals        qd;
  98.     #endif
  99.     
  100.     #undef __MPW_ONLY__
  101. #endif
  102.  
  103.  
  104.  
  105. /**\
  106. |**| ---------------------------------------------------------------------
  107. |**| main()
  108. |**| ---------------------------------------------------------------------
  109. \**/
  110. void main()
  111. {        
  112.     CursHandle            theCurs; 
  113.     long                theFeature;
  114.     Boolean                debuggingInitInstalled = false;
  115.     gxGraphicsClient     client;
  116.     
  117.     InitToolbox();
  118.     
  119.     theCurs = GetCursor(watchCursor);
  120.     SetCursor(*theCurs);
  121.  
  122.     CheckQuickDrawGX();
  123.     if (gQuitting)
  124.     {
  125.         SetCursor(&qd.arrow);
  126.         (void) StopAlert(rNoQuickDrawGXID, NULL);
  127.         return;
  128.     }
  129.  
  130.  
  131.     //
  132.     //    The QuickDraw GX gestaltGraphicsAttr Gestalt attribute can be used to determine if:
  133.     //    the graphics piece of GX has been loaded, the QuickDrawGX debugging init is installed,
  134.     //    or your are running the PowerPC version. 
  135.     //
  136.     //    In our case, we only need to know if the debugging init was installed. If it is,
  137.     //    we will enable the QuickDraw GX validation and notice handling features.We define 
  138.     //    debuggingInitInstalled as true to enable GX validation and notice handler
  139.     //  within the SetUpGXDebuggingWorld function.
  140.     //
  141.     if ( (Gestalt(gestaltGraphicsAttr, &theFeature) == noErr) )
  142.         if ( (theFeature & gestaltGraphicsIsDebugging) == gestaltGraphicsIsDebugging ) 
  143.          debuggingInitInstalled = true;
  144.     
  145.     
  146.     client = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  147.     
  148.     //
  149.     //    After we attempted to create the graphics client, we need to determine if the call
  150.     //  succeeded. If the call did not (as in the case for all GX functions), "client" will
  151.     //    be nil. If it is, we alert the user to the problem. Otherwise, we will attempted to 
  152.     //    allocate the GX heap below...
  153.     
  154.     if ( client ) 
  155.     {
  156.         //    Initialize the new graphics environment and create the GX heap.
  157.         
  158.         GXEnterGraphics();
  159.     
  160.         //
  161.         //    Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
  162.         //  call would not succeed is if there is not enough memory. In this case, the graphics 
  163.         //  error which will be posted is -27999 (out of memory). At this point, we have not 
  164.         //    installed an error handler, so we check for the error number corresponding to the 
  165.         //  out of memory error.
  166.         
  167.         if ( GXGetGraphicsError( nil ) != out_of_memory ) 
  168.         {
  169.             SetUpGXDebuggingWorld (debuggingInitInstalled);
  170.      
  171.             //
  172.             //    Create a window and attach a GX viewPort to it. By attaching the viewPort to 
  173.             //    the window will make sure that when a user moves or resizes the window all of
  174.             //    the GX drawing will occur within window. 
  175.             //
  176.             //    By the way, you cannot directly manipulate the parent viewPort attached to the
  177.             //    window, you will recieve a graphics error. This viewPort can only be manipulated
  178.             //  by the GX system. If you want to manipulate a viewPort attached to a window, it
  179.             //     _must_ be a child viewPort attached to the the parent viewPort attached to the
  180.             //    window.
  181.             
  182.             gWindow = GetNewWindow(rWindResource, nil, (WindowPtr)-1L);
  183.                                                  
  184.             gTheWindowsViewPort = GXNewWindowViewPort(gWindow);
  185.     
  186.             GXIgnoreGraphicsNotice(transform_already_set);
  187.             SetDefaultViewPort(gTheWindowsViewPort);
  188.             GXPopGraphicsNotice();
  189.     
  190.             
  191.             //    Create the GX shapes we are going to draw to the window. 
  192.             
  193.             DoInitialization(gWindow);
  194.     
  195.             SetCursor(&qd.arrow);  
  196.     
  197.             while (!gQuitting)
  198.                 EventLoop();           // loop until the window is closed
  199.     
  200.             // Leaving.  Close all the windows so we get rid of any data we or GX created.  Then,
  201.             // dispose of the common colors and exit the GX printing and graphics environment.
  202.     
  203.             DoDispose(gWindow);
  204.     
  205.             GXExitGraphics();     // Deallocate all of the default structures
  206.     
  207.         } else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");                
  208.     }  else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
  209.         
  210.     GXDisposeGraphicsClient(client);
  211. }
  212.  
  213.  
  214.  
  215. /**\
  216. |**| ---------------------------------------------------------------------
  217. |**| InitToolbox()
  218. |**| ---------------------------------------------------------------------
  219. \**/
  220. void InitToolbox (void)
  221. {
  222.     // Generic heap initialization.
  223.     
  224.     MaxApplZone(); 
  225.     MoreMasters(); MoreMasters(); MoreMasters(); 
  226.     MoreMasters(); MoreMasters(); MoreMasters(); 
  227.     
  228.     // Start up the toolbox so we can notify people if there's a problem
  229.     
  230.     InitGraf(&qd.thePort);
  231.     InitFonts();
  232.     InitWindows();
  233.     InitDialogs(nil);
  234.     InitCursor();
  235. }
  236.  
  237.  
  238. /**\
  239. |**| ---------------------------------------------------------------------
  240. |**| CheckQuickDrawGX()
  241. |**| Before making any calls, we'll see if QuickDraw GX is available.
  242. |**| If it's not, then set gQuitting=true so we can avoid doing any of 
  243. |**| the rest of this application.
  244. |**| ---------------------------------------------------------------------
  245. \**/
  246. void CheckQuickDrawGX (void)
  247. {
  248.     long                theFeature;
  249.  
  250.     // Before making any calls, we'll see if QuickDraw GX is available.  If it's not,
  251.     // we'll avoid doing any of the rest of this application
  252.     
  253.     if (Gestalt(gestaltGraphicsVersion, &theFeature) != noErr)
  254.         gQuitting = true;   // QuickDraw GX is not available
  255.     
  256. #ifdef powerc
  257.     // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed.
  258.     // Since we are "weak" linked to QuickDrawGXLib, the Process Manager will
  259.     // launch us even if QuickDrawGXLib is missing.  If it's missing, the
  260.     // Code Fragment Manager will leave the address of the functions we call
  261.     // unresolved, and we would crash if we tried to call that function.  So,
  262.     // we do a check here and should be prepared to exit gracefully if the 
  263.     // library is missing.  This could happen if the user has installed a
  264.     // 68K only version of QuickDraw GX.  It could also happen if the user has
  265.     // taken the QuickDraw GX extension out of the Extensions Folder.  
  266.     //
  267.     // Note - We could check this against any function we call in the library.
  268.     // GXNewGraphicsClient is the first function we call, so it's convenient.
  269.  
  270.     if ( (Ptr)GXNewGraphicsClient == (Ptr)kUnresolvedSymbolAddress ) 
  271.         gQuitting = true;   // QuickDraw GX is not available in Power Mac
  272. #endif
  273. }
  274.  
  275.  
  276. /**\
  277. |**| ---------------------------------------------------------------------
  278. |**| SetUpGXDebuggingWorld()
  279. |**| This function enables the GX error handling capabilities and validation
  280. |**| routines.  The validation routines are only enabled, if the user has  
  281. |**| installed the QuickDraw GX debugging init.  These routines are not
  282. |**| available with the non-debugging init. Calling them when they are not  
  283. |**| installed will not cause any problems, but it will cause unnecessary
  284. |**| work to be done by your application and the GX dispatcher.
  285. |**| ---------------------------------------------------------------------
  286. \**/
  287. void SetUpGXDebuggingWorld (Boolean debuggingInitInstalled)
  288. {
  289.       // 
  290.     //    We set-up GX validation, if the user has installed the "GXGraphics (debug)" init (formerly
  291.     //    named "aSecretGraphics.debug). This validation setting is the reccommended setting while
  292.     //    you are developing your GX application. As you increase the amount of validation, the drawing
  293.     //    speed will SLOW down due to all of the internal checking. 
  294.     //
  295.     //    For additional details regarding the various levels of validation, please see the
  296.     //    QuickDraw GX : Environment & Utilities book.
  297.     //
  298.     if ( debuggingInitInstalled ) GXSetValidation(gxPublicValidation + gxTypeValidation); 
  299.  
  300.     // 
  301.     //    Calling SetGraphicsLibraryErrors will install a GX error and warning handler. This
  302.     //    call is provided by the QuickDraw GX "graphics debugging library". Any time a GX error
  303.     //    or warning is generated, it will be posted to Macsbug.
  304.     //
  305.     SetGraphicsLibraryErrors ();
  306.         
  307.     //
  308.     //    If the user has installed the GX debugging version, we install a notice handler. Why? The
  309.     //    GX notice handling capabilities are only available with the debugging version.
  310.     //
  311.     if ( debuggingInitInstalled ) SetGraphicsLibraryNotices();
  312. }
  313.  
  314.  
  315.  
  316. /**\
  317. |**| ---------------------------------------------------------------------
  318. |**| EventLoop()
  319. |**| ---------------------------------------------------------------------
  320. \**/
  321. void EventLoop ()
  322. {
  323.     EventRecord event;
  324.  
  325.     if ( WaitNextEvent(everyEvent, &event, gSleep, nil) )
  326.         MyDoEvent(&event);
  327.     else
  328.         DoIdle(FrontWindow());
  329. }
  330.  
  331.  
  332. /**\
  333. |**| ---------------------------------------------------------------------
  334. |**| MyDoEvent()
  335. |**| ---------------------------------------------------------------------
  336. \**/
  337. void MyDoEvent (EventRecord *event)
  338. {
  339.     WindowPtr         window;        // temporarily used to hold 
  340.     GrafPtr            oldPort;
  341.     unsigned long    mssg;
  342.  
  343.     mssg = event->message;
  344.     switch(event->what)
  345.     {                    
  346.         case updateEvt:
  347.             BeginUpdate((WindowPtr) mssg);
  348.             SetPort(gWindow);
  349.             DoDraw(gWindow);
  350.             EndUpdate((WindowPtr) mssg);
  351.             break;
  352.  
  353.         case mouseDown:
  354.             DoMouseDown(event);
  355.             break;
  356.  
  357.         case osEvt:
  358.             if ( (mssg>>24)                        // if high byte of message indicates
  359.                     == suspendResumeMessage )    // this is suspend/resume event
  360.             {
  361.                 if (mssg & resumeFlag)            // if resume event
  362.                     gSleep = 0;                    // we're switching back from another app so speed up  
  363.                 else                            // if suspend event
  364.                     gSleep = 80;                // we're switching to another app so slow down...
  365.             }
  366.             break;
  367.                     
  368.     }
  369. }
  370.  
  371.  
  372. /**\
  373. |**| ---------------------------------------------------------------------
  374. |**| DoMouseDown
  375. |**| handle DoMouseDown events
  376. |**| ---------------------------------------------------------------------
  377. \**/
  378. void DoMouseDown (EventRecord *event)
  379. {
  380.     WindowPtr   window;
  381.     short       clickArea;
  382.     Rect        screenRect;
  383.  
  384.     clickArea = FindWindow( event->where, &window );
  385.     switch (clickArea)
  386.     {
  387.         case inSysWindow:
  388.             SystemClick(event, window);
  389.             break;
  390.                         
  391.         case inDrag:
  392.             screenRect = (**GetGrayRgn()).rgnBBox;
  393.                 DragWindow( window, event->where, &screenRect );
  394.             break;
  395.  
  396.         case inContent:
  397.             if ( window == FrontWindow())
  398.             {
  399.                  gxPoint        mouseLoc;
  400.                  Point        currMouseLoc;
  401.                  
  402.                  currMouseLoc.h = event->where.h;
  403.                  currMouseLoc.v = event->where.v;
  404.                  
  405.                 GXConvertQDPoint(&currMouseLoc, gTheWindowsViewPort, &mouseLoc);
  406.  
  407.                  DoClick(mouseLoc, gWindow);
  408.             }
  409.             else
  410.                  SelectWindow(window);
  411.             break;
  412.         
  413.         case inGoAway:
  414.             if ( TrackGoAway(window, event->where) )
  415.                 gQuitting = true;
  416.             break;
  417.         
  418.     }
  419. }
  420.             
  421.